今天要介紹的是網頁元件會用到的動畫,在 Day 07 已經介紹過過渡動畫這邊主要就是三大重點要定義:過渡類型( Transition Type)、持續時間(Duration)和 緩速效果(Easing)。
想先看 Code 或是 Demo 的由此去
Github Repo: ithelp-ui-demo
Live Demo:Storybook
在實作上,有個現成的好用東西叫 React Transition Group 可以用,而在 Vue 那邊則是直接有 Transition Mode 可以用。
它主要提供 Transition、CSSTransition、SwitchTransition 和 TransitionGroup 這四大元件給我們用。
Transition:最基本的 Transition 元件,用 style Attribute 操作 CSS。
CSSTransition:以 Transition 元件為基礎,進一步讓你可針對 CSS 做客製化。
SwitchTransition:可讓你運用 State 去切換想呈現的 Transition 效果。
TransitionGroup:讓你一次管理一整組元件的 Transition 特效。
在這邊會採用的是第二種 CSSTransition 元件,因為可以客製化 CSS,並運用 Tailwind Utility Class 的可以讓原生 CSS 去 Apply 的特性,可以更好地去定義 Transition 的效果,再加上使用 className 的效能會比 Style 好很多,所以選擇使用 CSSTransition。
但 Transition 的自由度一定是比較高的,這邊我可能日後會在修正,到時候也會補上新版的 Code,但今天先這樣 Demo!
元件的過場(Transition)都是由一個 Trigger 觸發(可能是點擊按鈕),並會定義起始狀態跟結束狀態(點擊前後的元件的狀態,像是 按鈕點擊後相應的元件會出現跟消失),依此可以再區分出以下四個時機點:
'entering'
:正要進入起始狀態的時間點(按鈕點擊後,元件準備出現的瞬間),像是 Modal 正準備出現。'entered'
:起始狀態過渡完成的時間點(元件出現的過渡動畫結束時的瞬間),像是 Modal 出現後的那個時間點。'exiting'
:與 entering 相反,正要進入結束狀態的時間點(按鈕再次點擊後,元件準備消失的瞬間),像是 Modal 正準備消失。'exited'
:與 enter 相反,結束狀態過渡完成的時間點(元件結束的過渡動畫結束的瞬間),像是 Modal 消失後的那個時間點。以下圖來說,元件要出現時,先是 entering 狀態什麼都沒有, Opacity 是 0,到 entered 元件出現後,opacity 變 1,並附上相應的 transition 屬性。
而元件要消失時,先進入 exiting 狀態,元件還存在所以opacity 是 1,到 exited 元件消失後, opacity 是 0,並也有相應的 transition 屬性。
而 CSSTransition 需要引入的 CSS 設定會是這樣:
.className-enter {
opacity: 0;
}
.className-enter-active {
opacity: 1;
transition: opacity 200ms;
}
.className-exit {
opacity: 1;
}
.className-exit-active {
opacity: 0;
transition: opacity 200ms;
}
接下來就介紹在 React Transition Group 為 Transition 設計了怎樣的介面,提供了哪些 Props,除了下圖以外還有一些 Props (像 appear, addEnd Listener 等等),但這邊沒用到就先不贅述。
元件的實作就這樣直接使用套件,但只有這樣的話就太沒誠意了,因此在這邊會實作 Fade 來 Demo 給大家看!
import { CSSTransition } from "react-transition-group";
import { CSSTransitionProps } from "react-transition-group/CSSTransition";
import './fade.css';
export interface FadeProps extends CSSTransitionProps {
}
export const Fade: React.FC<CSSTransitionProps> = (props) => {
const {
children,
...rest
} = props;
return (
<CSSTransition
timeout={300}
unmountOnExit
classNames="fade"
{...rest}
>
{children}
</CSSTransition>
)
}
.fade-enter {
opacity: 0;
transform: scale(0.9);
}
.fade-enter-active {
opacity: 1;
transform: translateX(0);
transition: opacity 300ms, transform 300ms;
}
.fade-exit {
opacity: 1;
}
.fade-exit-active {
opacity: 0;
transform: scale(0.9);
transition: opacity 300ms, transform 300ms;
}
這邊其實還是把 TransitionType、Duration 跟 Easing 寫死,但如之前所說,這部份應該是要在 Design System 中會定義出幾個固定的值,讓整個網頁的過渡效果都一致,但這次 Demo 做得比較趕沒時間去做更彈性的處理,等這系列的文章都發完後還有空的話,會再上來重構一下的!
今天的東西可能有點水,但重點在介紹 React-Transition-Group 這個好東西給大家,跟 Design System 更有關聯的許多客製化希望能再日後會再補上更好的版本,這邊就先請讀者見諒了!
那 Design System 的篇章就到今天結束了,對於設計還想知道的話可以參考 Material Design ,而實作的部分真的是透過 Tailwind 就能實現大部分了,這邊是透過 Color 給大家感受一下,Typography 是比較特別也有趣的實作,而 Icon 跟 Transition 則是提供給大家一種作法,其實還有很多種其他的實作方式的!
明天開始會進入 元件們的 UML 環節,談談 UI 元件們彼此之間的關係,理解網頁中 UI 元件的階層關係,像是哪些元件是最先需要實作的 、哪些元件是怎麼被組成的等等,而這些關係在軟體設計中是可以透過 UML 的元件圖來呈現的。
那就明天見囉!